//
//@File    :	14.22_frnd2tmp.cpp
//@Time    :	2022/02/24 11:37:41
//@Auther  :	Sun Sheng
//@Contact :	970340843@qq.com
//@Desc    :	template class with non-template friends
//

//模板类声明也可以有友元
//1.非模板友元
//2.约束(bound)模板友元,即友元的类型取决于类被实例化的类型
//3.非约束(unbound)模板友元,即友元的所有具体化都是类的每一个具体化的友元

#include <iostream>
using std::cout;
using std::endl;

template <typename T>
class HasFriend
{
private:
    T item;
    static int ct;

public:
    HasFriend(const T &i):item(i){ct++;}
    ~HasFriend(){ct--;}
    friend void counts();
    friend void reports(HasFriend<T> &);//template parameter
};

template <typename T>
int HasFriend<T>::ct=0;

void counts(){
    cout<<"int count: "<<HasFriend<int>::ct<<": ";
    cout<<"double count: "<<HasFriend<double>::ct<<endl;
}

void reports(HasFriend<int> & hf)
{
    cout<<"HasFriend<int>: "<<hf.item<<endl;
}
void reports(HasFriend<double> & hf)
{
    cout<<"HasFriend<double>: "<<hf.item<<endl;
}
int main()
{
    cout<<"No objects declared: ";
    counts();
    HasFriend<int> hfi1(10);
    cout<<"After hfi1 declared: ";
    counts();
    HasFriend<int> hfi2(20);
    cout<<"After hfi2 declared: ";
    counts();
    HasFriend<double> hfdb(10.5);
    cout<<"After hfdb declared: ";
    counts();
    reports(hfi1);
    reports(hfi2);
    reports(hfdb);

    system("pause");
    return 0;
}